package coder.nav.service;

import cn.hutool.core.bean.BeanUtil;
import coder.nav.enums.NavMemoTypeEnums;
import coder.nav.enums.NavSettingEnums;
import coder.nav.mapper.NavMemoMapper;
import coder.nav.model.NavMemo;
import coder.nav.model.bo.NavSaveMemoBO;
import coder.nav.model.bo.SaveIsExpandBO;
import coder.nav.model.vo.NavMemoTreeVO;
import coder.nav.model.vo.NavMemoVO;
import coder.nav.schedule.action.NavTaskDayCashAction;
import coder.nav.utils.JwtUtils;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import org.apache.commons.collections4.CollectionUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.stereotype.Service;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.text.SimpleDateFormat;
import java.util.*;
import java.util.stream.Collectors;

@Service
public class NavMemoService extends ServiceImpl<NavMemoMapper, NavMemo> {

    /**
     * 保存
     * @param bo 入参
     */
    public NavMemoVO saveMemo(NavSaveMemoBO bo) {
        NavMemo entity = BeanUtil.copyProperties(bo, NavMemo.class);
        entity.setUserId(JwtUtils.getUserId());
        if(StringUtils.isBlank(entity.getIcon())) {
            String icon = Objects.equals(entity.getType(), 0) ? NavMemoTypeEnums.DIRECTORY.getIcon() : NavMemoTypeEnums.FILE.getIcon();
            entity.setIcon(icon);
        }
        if(Objects.isNull(entity.getId())) {
            SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMdd");
            entity.setSort(Integer.valueOf(sdf.format(new Date())));
            this.baseMapper.insert(entity);
        }
        this.baseMapper.updateById(entity);
        return BeanUtil.copyProperties(entity, NavMemoVO.class);
    }

    /**
     * 删除
     * @param id 主键id
     */
    public int deleteMemo(Long id) {
        List<Long> childrenIds = this.getChildrenIds(id);
        childrenIds.add(id);
        // 增加回收站逻辑
        // return this.baseMapper.deleteBatchIds(childrenIds);
        LambdaUpdateWrapper<NavMemo> updateWrapper = new LambdaUpdateWrapper<>();
        updateWrapper.in(NavMemo::getId, childrenIds);
        NavMemo entity = new NavMemo();
        entity.setIsDeleted(1);
        return this.baseMapper.update(entity, updateWrapper);
    }

    /**
     * 恢复
     * @param id 主键id
     */
    public int recoverMemo(Long id) {
        List<Long> childrenIds = this.getChildrenIds(id);
        childrenIds.add(id);
        LambdaUpdateWrapper<NavMemo> updateWrapper = new LambdaUpdateWrapper<>();
        updateWrapper.in(NavMemo::getId, childrenIds);
        NavMemo entity = new NavMemo();
        entity.setIsDeleted(0);
        return this.baseMapper.update(entity, updateWrapper);
    }

    /**
     * 清空回收站
     */
    public int cleanRecycle() {
        LambdaQueryWrapper<NavMemo> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(NavMemo::getUserId, JwtUtils.getUserId());
        queryWrapper.eq(NavMemo::getIsDeleted, 1);
        return this.baseMapper.delete(queryWrapper);
    }

    /**
     * 彻底删除
     * @param id 主键id
     */
    public int cleanMemo(Long id) {
        List<Long> childrenIds = this.getChildrenIds(id);
        childrenIds.add(id);
        return this.baseMapper.deleteBatchIds(childrenIds);
    }
    
    /**
     * 获取所有子节点id
     * @param id 主键id
     */
    public List<Long> getChildrenIds(Long id) {
        LambdaQueryWrapper<NavMemo> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(NavMemo::getParentId, id);
        List<NavMemo> childrenList = this.baseMapper.selectList(queryWrapper);
        if(CollectionUtils.isNotEmpty(childrenList)) {
            List<Long> childrenIds = childrenList.stream().map(NavMemo::getId).collect(Collectors.toList());
            List<Long> newIds = new ArrayList<>();
            for(Long childrenId : childrenIds) {
                List<Long> tempIds = this.getChildrenIds(childrenId);
                if(CollectionUtils.isNotEmpty(tempIds)) {
                    newIds.addAll(tempIds);
                }
                newIds.add(childrenId);
            }
            return newIds.stream().distinct().collect(Collectors.toList());
        }
        return new ArrayList<>();
    }

    /**
     * 详情
     * @param id 主键id
     */
    public NavMemoVO getInfo(Long id) {
        LambdaQueryWrapper<NavMemo> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(NavMemo::getUserId, JwtUtils.getUserId());
        queryWrapper.eq(NavMemo::getId, id);
        NavMemo entity = this.baseMapper.selectOne(queryWrapper);
        return BeanUtil.copyProperties(entity, NavMemoVO.class);
    }

    /**
     * 目录
     */
    public List<NavMemoTreeVO> getFolder() {
        List<NavMemoTreeVO> list = this.getTree(0);
        return this.getFolder(list, 0);
    }

    /**
     * 目录
     * @param list 需要处理的数据
     * @param level 目录层级
     */
    public List<NavMemoTreeVO> getFolder(List<NavMemoTreeVO> list, int level) {
        if(CollectionUtils.isEmpty(list)) {
            return new ArrayList<>();
        }
        List<NavMemoTreeVO> result = new ArrayList<>();
        for(NavMemoTreeVO item : list) {
            if(item.getType() == 1) {
                continue;
            }
            // 标题
            StringBuilder title = new StringBuilder();
            if(level == 0) {
                title.append(NavSettingEnums.MEMO.getIcon());
                title.append(" ");
            }
            for(int i = 0; i < level; i++) {
                String icon = StringUtils.isNotBlank(item.getIcon()) ? item.getIcon() : NavMemoTypeEnums.DIRECTORY.getIcon();
                title.append(i == level - 1 ? icon + " " : "　 ");
            }
            title.append(item.getTitle());
            item.setTitle(title.toString());

            List<NavMemoTreeVO> children = this.getFolder(item.getChildren(), level + 1);

            item.setChildren(null);
            result.add(item);

            if(CollectionUtils.isNotEmpty(children)) {
                result.addAll(children);
            }
        }
        return result;
    }

    /**
     * 树
     */
    public List<NavMemoTreeVO> getTree() {
        return this.getTree(null);
    }

    /**
     * 树
     * @param memoType 节点类型
     */
    public List<NavMemoTreeVO> getTree(Integer memoType) {
        // 1.编辑器
        List<NavMemoTreeVO> result = new ArrayList<>();
        if(Objects.isNull(memoType)) {
            NavMemoTreeVO ide = new NavMemoTreeVO();
            ide.setId(-1L);
            ide.setType(NavMemoTypeEnums.DIRECTORY.getKey());
            ide.setTitle("Coder-IDE");
            result.add(ide);
        }

        // 2.记事本
        LambdaQueryWrapper<NavMemo> memoWrapper = new LambdaQueryWrapper<>();
        memoWrapper.eq(NavMemo::getUserId, JwtUtils.getUserId());
        memoWrapper.eq(NavMemo::getIsDeleted, 0);
        List<NavMemo> memoList = this.baseMapper.selectList(memoWrapper);
        List<NavMemoTreeVO> memoTree = new ArrayList<>();
        if(CollectionUtils.isNotEmpty(memoList)) {
            memoTree = this.buildTree(BeanUtil.copyToList(memoList, NavMemoTreeVO.class));
        }
        NavMemoTreeVO memo = new NavMemoTreeVO();
        memo.setId(0L);
        memo.setType(NavMemoTypeEnums.DIRECTORY.getKey());
        memo.setTitle("记事本");
        memo.setChildren(memoTree);
        result.add(memo);

        if(Objects.nonNull(memoType)) {
            return result;
        }

        // 3.回收站
        LambdaQueryWrapper<NavMemo> recycleWrapper = new LambdaQueryWrapper<>();
        recycleWrapper.eq(NavMemo::getUserId, JwtUtils.getUserId());
        recycleWrapper.eq(NavMemo::getIsDeleted, 1);
        List<NavMemo> recycleList = this.baseMapper.selectList(recycleWrapper);
        List<NavMemoTreeVO> recycleTree = new ArrayList<>();
        if(CollectionUtils.isNotEmpty(recycleList)) {
            recycleTree = this.buildTree(BeanUtil.copyToList(recycleList, NavMemoTreeVO.class));
        }
        NavMemoTreeVO recycle = new NavMemoTreeVO();
        recycle.setId(-99L);
        recycle.setType(NavMemoTypeEnums.DIRECTORY.getKey());
        recycle.setTitle("回收站");
        recycle.setChildren(recycleTree);
        result.add(recycle);

        return result;
    }

    /**
     * 构建树结构
     * @param nodes 节点数据
     */
    public List<NavMemoTreeVO> buildTree(List<NavMemoTreeVO> nodes) {
        Map<Long, NavMemoTreeVO> nodeMap = new HashMap<>();
        List<NavMemoTreeVO> rootList = new ArrayList<>();
        // 将所有节点放入 map 中，方便查找
        for(NavMemoTreeVO node : nodes) {
            nodeMap.put(node.getId(), node);
        }
        // 构建树结构
        for(NavMemoTreeVO node : nodes) {
            if (node.getParentId() == 0) {
                // 如果 parentId 为 0，说明是根节点
                rootList.add(node);
            } else {
                // 否则找到父节点，并将当前节点添加到父节点的 children 中
                NavMemoTreeVO parent = nodeMap.get(node.getParentId());
                if (parent == null) {
                    rootList.add(node);
                } else {
                    parent.getChildren().add(node);
                    parent.getChildren().sort((o1, o2) -> o2.getSort().compareTo(o1.getSort()));
                }
            }
        }
        return this.sortTree(rootList);
    }

    /**
     * 排序
     * @param nodes 节点数据
     */
    public List<NavMemoTreeVO> sortTree(List<NavMemoTreeVO> nodes) {
        if(CollectionUtils.isEmpty(nodes)) {
            return new ArrayList<>();
        }
        List<NavMemoTreeVO> rootList = new ArrayList<>();
        for(NavMemoTreeVO node : nodes) {
            List<NavMemoTreeVO> children = this.sortTree(node.getChildren());
            if(CollectionUtils.isNotEmpty(children)) {
                // node.setSort(children.get(0).getSort());
                node.setChildren(children);
            }
            rootList.add(node);
        }
        rootList.sort((o1, o2) -> o2.getSort().compareTo(o1.getSort()));
        return rootList;
    }

    /**
     * 保存节点展开
     * @param bo 入参
     */
    public void saveIsExpand(SaveIsExpandBO bo) {

        if(CollectionUtils.isEmpty(bo.getFolderIds())) {
            return;
        }
        // 删除所有节点展开状态
        LambdaUpdateWrapper<NavMemo> originUpdateWrapper = new LambdaUpdateWrapper<>();
        originUpdateWrapper.eq(NavMemo::getUserId, JwtUtils.getUserId())
                .eq(NavMemo::getType, 0)
                .set(NavMemo::getIsExpand, 0);
        this.update(originUpdateWrapper);
        //
        LambdaUpdateWrapper<NavMemo> editUpdateWrapper = new LambdaUpdateWrapper<>();
        editUpdateWrapper.eq(NavMemo::getUserId, JwtUtils.getUserId())
                .in(NavMemo::getId, bo.getFolderIds())
                .eq(NavMemo::getType, 0)
                .set(NavMemo::getIsExpand, 1);
        this.update(editUpdateWrapper);

    }

    /**
     * 获取节点展开
     */
    public List<Long> getIsExpand() {
        LambdaQueryWrapper<NavMemo> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(NavMemo::getUserId, JwtUtils.getUserId())
                .eq(NavMemo::getType, 0)
                .eq(NavMemo::getIsExpand, 1);
        List<NavMemo> list = this.list(queryWrapper);
        List<Long> result = list.stream().map(NavMemo::getId).collect(Collectors.toList());
        result.add(0, 0L);
        result.add(-99L);
        return result;
    }
    
    /**
     * 获取 coder.nav 目录下文件
     * @param lang 语言
     * @param userId 用户id
     */
    public List<NavMemo> getCoderNavPackage(String lang, Long userId) {
        if(Objects.isNull(userId)) {
            userId = JwtUtils.getUserId();
        }
        LambdaQueryWrapper<NavMemo> coderNavQueryWrapper = new LambdaQueryWrapper<>();
        coderNavQueryWrapper.eq(NavMemo::getUserId, userId)
                .eq(NavMemo::getTitle, "coder.nav");
        List<NavMemo> utilsList = this.list(coderNavQueryWrapper);
        if(CollectionUtils.isEmpty(utilsList)) {
            return new ArrayList<>();
        }
        NavMemo utils = utilsList.get(0);
        LambdaQueryWrapper<NavMemo> langQueryWrapper = new LambdaQueryWrapper<>();
        langQueryWrapper.eq(NavMemo::getUserId, userId)
                .eq(NavMemo::getParentId, utils.getId())
                .eq(NavMemo::getTitle, lang.toLowerCase());
        List<NavMemo> langList = this.list(langQueryWrapper);
        if(CollectionUtils.isEmpty(langList)) {
            return new ArrayList<>();
        }
        NavMemo langFolder = langList.get(0);
        LambdaQueryWrapper<NavMemo> utilsQueryWrapper = new LambdaQueryWrapper<>();
        utilsQueryWrapper.eq(NavMemo::getUserId, userId)
                .eq(NavMemo::getParentId, langFolder.getId());
        return this.list(utilsQueryWrapper);
    }

    /**
     * 分享内容
     * @author Bosen 2025/11/9 14:33
     */
    public NavMemoVO shareInfo(Long userId, String shareId) {
        LambdaQueryWrapper<NavMemo> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(NavMemo::getUserId, userId);
        queryWrapper.eq(NavMemo::getShareId, shareId);
        NavMemo entity = this.baseMapper.selectOne(queryWrapper);
        return BeanUtil.copyProperties(entity, NavMemoVO.class);
    }

}
